/**
 * 规则：
 * 		- 邮箱      首位字符和 @ 字符之间用 * 替换，例：g****@gq.com;
 * 		- VIN码    显示前3后4，中间 * 代替，例：LGJ*************0652
 *    - 姓名      第一个字替换为*号。例:*ndy;
 *    - 车牌号码   保留前二后一，中间替换为4位*号。例:鄂 A****9;
 *    // 以下都是默认
 *    - ICCID    保留前三后四，中间替换为4位*号。例:898****0615;
 *    - MSISDN   保留前三后四，中间替换为4位*号。例:139****0615;
 *    - IMSI:    保留前三后四，中间替换为4位*号。例:898****0615;
 *    - 手机      保留前三后四，中间替换为4位*号。例:1877****6765;
 *    - 默认      保留前三后四，中间替换为4位*号。例:898****0615;
 * 交互：鼠标悬浮可以看到全部
 */
import React from 'react';
import { Tooltip } from 'antd';
import { isNil, isString } from 'lodash';

const typeArr = [
  'name',  // 名称
  'phone', // 手机
  'simCard', // sim卡
  'email',  // 邮箱
  'plate', // 车牌号
  'identity', // 身份证
  'location', // 地理位置
  'longitude', // 经度
  'latitude', // 纬度
  'uid',    // uid
  'trip',  // 行程
  'bankCard',  // 银行卡
  'landline', // 座机
  'accept', // 接受对象
  'audience', // 受众对象
  'fax',   // 传真
] as const;

export type FormatTypes = (typeof typeArr)[number];

interface MaskTextProps {
  text: string | null; // 原文
  auth?: string; // 权限，暂未使用
  mask?: string; // 掩码符号
  emptyHolder?: string; // 没有数据展示
  type?: FormatTypes;
}

interface RuleOption {
  regExp: RegExp;
  length?: number;
}

// 登录账户, 账户名称, 姓名,第一个字符替换为*，如*ftc_malin, 位数要求:无
export const nameExp = /(^)(^.)(.*)/;

// 手机号, SIM卡,座机号，传真 保留前三后四，中间替换为4位*，如159****8888, 位数要求: 11
export const phoneExp = /(^\d{3})(.{4,})(\d{4}$)/;
// 邮箱 第一个字符之后，@之前替换为4位*，如 m****@gmail.com,, 位数要求:无
export const emailExp = /(^[A-Za-z1-9])([\w\-\.]+)(@[\w-\.]+)$/;

// 车牌号 保留前二后一，中间替换为4位*，如 鄂A****8, 位数要求：7、8
export const plateExp = /(^.{2})(.{4,5})(.$)/;

//身份证号 保留前6后4，中间替换为8位*，如110105********1530 , 位数要求：18
export const identityExp = /(^\d{6})(\d{8})(\d{3}\w$)/;

// 地理位置  显示前一位和最后一位，中间以四个*号脱敏, 位数要求：无
export const locationExp = /(^.)(.+)(.$)/;

// 经纬度 保留整数，小数替换为2位*，如12.**, 位数要求：无
export const floatExp = /(^\d+\.)(.+)($)/;

// UID  保留前三位和最后一位，中间用四个*脱敏, 位数要求：无
export const uidExp = /(^.{3})(.+)(.$)/;

// 行程起点  显示前一位和最后一位，中间以四个*号脱敏 位数要求：无
// 行程终点  显示前一位和最后一位，中间以四个*号脱敏 位数要求：无
export const tripExp = /(^.)(.+)(.$)/;

// 银行卡号  保留后四位，前面的数字以*脱敏，如************1234, 位数要求：无
export const bankCardExp = /(^\d+)(\d{4}$)($)/;
// 接收对象,受众对象  保留前四后四，中间替换为*，如1234*****5678
export const acceptObjectExp = /(^.{4})(.*)(.{4}$)/;

export const formatFn = (options: {
  val: string;
  regExp: RegExp;
  mask?: string;
  length?: number;
}) => {
  let { val, regExp, mask = '*', length } = options;
  return val.replace(regExp, (_: string, start: string, value: string, end: string) => {
    return `${start}${mask.repeat(length || value.length)}${end}`;
  });
};

export default (props: MaskTextProps) => {
  const { text, mask = '*', emptyHolder = '-', type = 'name' } = props;

  if (isNil(text)) {
    return emptyHolder;
  }

  if (!isString(text)) {
    return text;
  }
  const expMap = new Map<FormatTypes, RuleOption>([
    ['name', { regExp: nameExp }],
    ['phone', { regExp: phoneExp, length: 4 }],
    ['simCard', { regExp: phoneExp, length: 4 }],
    ['email', { regExp: emailExp, length: 4 }],
    ['plate', { regExp: plateExp, length: 4 }],
    ['identity', { regExp: identityExp, length: 8 }],
    ['location', { regExp: locationExp, length: 4 }],
    ['longitude', { regExp: floatExp, length: 2 }],
    ['latitude', { regExp: floatExp, length: 2 }],
    ['uid', { regExp: uidExp, length: 4 }],
    ['trip', { regExp: tripExp, length: 4 }],
    ['bankCard', { regExp: bankCardExp }],
    ['landline', { regExp: phoneExp, length: 4 }],
    ['fax', { regExp: phoneExp, length: 4 }],
    ['accept', { regExp: acceptObjectExp }],
    ['audience', { regExp: acceptObjectExp }],
  ]);

  let expRegOption = expMap.get(type);
  
  if (expRegOption && expRegOption.regExp && expRegOption.regExp.test(text)) {
    return (
      <Tooltip title={text}>
        <span>{formatFn({ ...expRegOption, mask, val: text }) }</span>
      </Tooltip>
    )
  }
  return text
};
